<!DOCTYPE html>
<html>

<head>
  <title>Quarkus Insights #1: Tests</title>
  <script id="adobe_dtm" src="https://www.redhat.com/dtm.js" type="text/javascript"></script>
  <script src="/assets/javascript/highlight.pack.js" type="text/javascript"></script>
  <META HTTP-EQUIV='Content-Security-Policy' CONTENT="default-src 'none'; script-src 'self' 'unsafe-eval' 'sha256-ANpuoVzuSex6VhqpYgsG25OHWVA1I+F6aGU04LoI+5s=' 'sha256-ipy9P/3rZZW06mTLAR0EnXvxSNcnfSDPLDuh3kzbB1w=' js.bizographics.com https://www.redhat.com assets.adobedtm.com jsonip.com https://ajax.googleapis.com https://www.googletagmanager.com https://www.google-analytics.com https://use.fontawesome.com; style-src 'self' https://fonts.googleapis.com https://use.fontawesome.com; img-src 'self' *; media-src 'self' ; frame-src https://www.googletagmanager.com https://www.youtube.com; frame-ancestors 'none'; base-uri 'none'; object-src 'none'; form-action 'none'; font-src 'self' https://use.fontawesome.com https://fonts.gstatic.com;">
  <META HTTP-EQUIV='X-Frame-Options' CONTENT="DENY">
  <META HTTP-EQUIV='X-XSS-Protection' CONTENT="1; mode=block">
  <META HTTP-EQUIV='X-Content-Type-Options' CONTENT="nosniff">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="Quarkus: Supersonic Subatomic Java">
  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:site" content="@QuarkusIO"> 
  <meta name="twitter:creator" content="@QuarkusIO">
  <meta property="og:url" content="https://quarkus.io/blog/insights-1/" />
  <meta property="og:title" content="Quarkus Insights #1: Tests" />
  <meta property="og:description" content="Quarkus: Supersonic Subatomic Java" />
  <meta property="og:image" content="/assets/images/quarkus_card.png" />
  <link rel="canonical" href="https://quarkus.io/blog/insights-1/">
  <link rel="shortcut icon" type="image/png" href="/favicon.ico" >
  <link rel="stylesheet" href="https://quarkus.io/guides/stylesheet/config.css" />
  <link rel="stylesheet" href="/assets/css/main.css" />
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
  <link rel="alternate" type="application/rss+xml"  href="https://quarkus.io/feed.xml" title="Quarkus">
  <script src="https://quarkus.io/assets/javascript/goan.js" type="text/javascript"></script>
  <script src="https://quarkus.io/assets/javascript/hl.js" type="text/javascript"></script>
</head>

<body class="post">
  <!-- Google Tag Manager (noscript) -->
  <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-NJWS5L"
  height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->

  <div class="nav-wrapper">
  <div class="grid-wrapper">
    <div class="width-12-12">
      <input type="checkbox" id="checkbox" />
      <nav id="main-nav" class="main-nav">
  <div class="container">
    <div class="logo-wrapper">
      
        <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_600px_reverse.png" class="project-logo" title="Quarkus"></a>
      
    </div>
    <label class="nav-toggle" for="checkbox">
      <i class="fa fa-bars"></i>
    </label>
    <div id="menu" class="menu">
      <span>
        <a href="/get-started/" class="">Get Started</a>
      </span>
      <span>
        <a href="/guides/" class="">Guides</a>
      </span>
      <span>
        <a href="/community/" class="">Community</a>
      </span>
      <span>
        <a href="/support/" class="">Support</a>
      </span>
      <span>
        <a href="/blog/" class="active">Blog</a>
      </span>
      <span>
        <a href="https://code.quarkus.io" class="button-cta secondary white">Start Coding</a>
      </span>
    </div>
  </div>
      </nav>
    </div>
  </div>
</div>

  <div class="content">
    <div class="post-page grid-wrapper">
  <div class="width-8-12 width-12-12-m doc-content">
    <div class="grid-wrapper">
      <div class="width-12-12">
        <p>
          <a href="/blog"><i class="fas fa-angle-left"></i> Back to all posts</a>
        </p>
      </div>
      <div class="width-12-12">
        <div class="post-date">
          May 08, 2020 
          
            <span class="tags"><a href="/blog/tag/insights">#insights</a></span>
          
        </div>
        <h1 class="post-title">Quarkus Insights #1: Tests</h1>
        <div class="grid-wrapper">
          <div class="width-8-12 width-12-12-m byline-wrapper">
            
            
              <img class="headshot" src="https://www.gravatar.com/avatar/9ac47c2c99739d75d633f4d9b73eef35">
            
            <p class="byline">By Max Rydahl Andersen</p>
          </div>
          <div class="width-12-12">
              <div class="paragraph">
<p>Monday we went live with <a href="https://www.youtube.com/watch?v=OCPFdpvL1Q0">Quarkus Insights #1: Testing</a> with Georgios showing and talking about all things Testing. Especially showing the new Mockito integration and examples of TestContainer usage.</p>
</div>
<div class="videoblock">
<div class="content">
<iframe width="640" height="360" src="https://www.youtube.com/embed/OCPFdpvL1Q0?rel=0" frameborder="0" allowfullscreen></iframe>
</div>
</div>
<div class="paragraph">
<p>The code he shows are at <a href="https://github.com/geoand/quarkus-test-demo" class="bare">https://github.com/geoand/quarkus-test-demo</a> and below are a transcript (Thanks Markus!).</p>
</div>
<div class="sect1">
<h2 id="next-episode"><a class="anchor" href="#next-episode"></a>Next Episode</h2>
<div class="sectionbody">
<div class="paragraph">
<p>On Tusday May 12th 11:15 CEST / 14:45 IST / 05:15 EST  we will do <a href="https://www.youtube.com/watch?v=5UhM_W6zukg">Quarkus Insights episode #2: quarkus:dev &amp; command mode</a> with <a href="https://twitter.com/stuartwdouglas">Stuart Douglas</a>!</p>
</div>
<div class="paragraph">
<p>This is at a more European/APAC time friendly slot - anyone that shows up from United states gets a shout out for being up way too early!</p>
</div>
<div class="paragraph">
<p>We will talk about how to use <code>quarkus:dev</code> and the new command mode - knowing Stuart we will also get to digg deep into the internals of Quarkus.</p>
</div>
<div class="paragraph">
<p>Do add questions to the youtube video already or show up on the live show and ask away - we will cover as much as we can!</p>
</div>
<div class="paragraph">
<p>To join current live show or see the next one scheduled bookmark this link: <a href="https://youtube.com/quarkusio/live" class="bare">https://youtube.com/quarkusio/live</a></p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="transcript"><a class="anchor" href="#transcript"></a>Transcript</h2>
<div class="sectionbody">
<div class="paragraph">
<p>Below is a transcription of the episode.</p>
</div>
<div class="paragraph">
<p>Kudos to Markus Eisele for making this happen!</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: Quarkus Inside number one. Test.</p>
</div>
<div class="paragraph">
<p>Well, Hello everyone. And we&#8217;re cheap on the budget right now.</p>
</div>
<div class="paragraph">
<p>Alright, so I&#8217;m not alone in this madness. Welcome to this new episode of Quarkus Inside. It&#8217;s an official one, in the sense that it&#8217;s not a meta subject. We&#8217;re gonna have real conversations around test today and to have conversation here. I do have Max, my colegue and partner in crime, but also Georgios which has been a massive contributor to Quarkus, being left and right, so maybe Georgios, do you wanna introduce yourself?</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Yeah, thanks, thanks, you Emmanuel.</p>
</div>
<div class="paragraph">
<p>Yeah, my name is Georgios or George as it would be spelled in English. I&#8217;ve been with Red Hat for a couple of years, but my life really changed when the great folks that started Quarkus really announced it internally, and I had a massive way. Oh man, I gotta jump on to this thing. It&#8217;s beyond what I could ever imagine. So yeah, I started contributing nesting for spring stuff and then just took it from there basically. Now trying to do, like you said, things left or right.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: So I guess to&#8230;&#8203; I&#8217;ll speak in the name of the great folks of Quarkus it&#8217;s like "Thanks God, Georgios is here", 'cause you jump on every trouble we have. It&#8217;s been a great, great experience.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Thank you thinking very much.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: Alright, so, Max, do you wanna say a few things before we&#8230;&#8203; We go to the&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p><strong>Max</strong>: So, yes, a few things. I hopefully should have fixed my sound now and Emmanuel should have stopped sending out my sound twice.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: Yes.</p>
</div>
<div class="paragraph">
<p><strong>Max</strong>: That&#8217;s less weird.</p>
</div>
<div class="paragraph">
<p>And other thing is that we actually, over the weekends, our channel actually went from around 8-900 to, now past a thousand that&#8217;s cool.</p>
</div>
<div class="paragraph">
<p>Yeah, so we need to do this. And over the weekend we had another thing: Tim Fox started thread a about how you pronounced Quarkus and since it&#8217;s a long, a long thread. So I&#8217;m just wondering how you guys pronouncing it. So mine is Quarkus.</p>
</div>
<div class="paragraph">
<p>What&#8217;s yours Emmanuel?</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: To me it&#8217;s like, "Spartakus" or it&#8217;s Quarkus. But I&#8217;m Frensh so who knows.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: And I was on a, I say, Quarkus.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: Yeah, 1.02k you guys send that? And that&#8217;s the Tim Fox threat for the conversation. And I love when British talks to British about pronunciation, or can&#8230;&#8203; Yeah, I always just love it.</p>
</div>
<div class="paragraph">
<p><strong>Max</strong>: It was tomato tomato, data, data. Yeah, the whole thing. Anyway, I accept all pronunciation of Quarkus, it&#8217;s fine.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: Yes, it&#8217;s. You know the worst was Cylon. Exactly this one was like really difficult so we did better for Quarkus&#8230;&#8203; Alright.</p>
</div>
<div class="paragraph">
<p><strong>Max</strong>: The last thing I had was: So we published an article, like a blog with the video, that we did last time and we added the transcription in there, which I think works pretty nice, like last time, is we didn&#8217;t talk about technical hopefully today, George gonna tell us all good things you have to know about testing. So it might be more useful. If anyone wanna say that&#8217;s useful or we should keep doing that! All done by Markus Eisele. He volunteered to do it. So pretty awesome. It&#8217;s also actually the sub-titles.</p>
</div>
<div class="paragraph">
<p>So if you go and you don&#8217;t standing neither Emmanuel&#8217;s French English or my mumbling Danish. There&#8217;s now sub-titles!</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: Transcripts here and subtitles in the video itself you mean?</p>
</div>
<div class="paragraph">
<p><strong>Max</strong>: Yeah, so if you go to the videos, there is one whatever Google recognize which I kept there just for entertainment value, the one that I&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: Where do I go, I guess, videos&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p><strong>Max</strong>: Yeah you click on the video and then you see the&#8230;&#8203; the CC, in the corner. So you just dump in the text and then Google figure out where the timestamps are. I was pretty impressed it&#8217;s&#8230;&#8203; Is it good? Would be good if the time spent&#8230;&#8203; is something that people like to for that was&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: Anyway, that was the production of things here. Receiving our stuff are&#8230;&#8203; Yeah, alright, so we&#8217;re ready. We can share the screen of Georgios, but today we&#8217;re going to talk about tests in Quarkus. So Is a Java framework, so I just use JUnit and off I go right? Or is it a bit more complicated?</p>
</div>
<div class="paragraph">
<p>What do you guys think?</p>
</div>
<div class="paragraph">
<p>0:05:35 S1:</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Well, like all things in life. I think it&#8217;s a little more complicated but not too much, not too much. If you&#8217;re a regular enterprise Java developer no problem at all, it usesall the stuff you already know. So yeah, you&#8217;ll have to use a couple of new annotations or whatever, but you just pick up the regular libraries, you already know we&#8217;ll show QuarKito we&#8217;ll show WireMock, AssertJ. So all good, you just have to understand how these fit in with the Quarkus ecosystem, but other that, all good.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: Okay, by the way. So here, it&#8217;s not about Test, but John says, "Hey how do you pronouce pronouciation?" ;]</p>
</div>
<div class="paragraph">
<p>So it says "prononciation" in French, so there you go to not&#8230;&#8203; But, more seriously, if you have questions, what we are having conversation with Georgios around test, so we&#8217;re gonna pretend we&#8217;re having&#8230;&#8203; Well, not that pretending actually, but we&#8217;re gonna have questions to Georgios and ask questions, but if you do have questions on your own, just send them to the comments and will push a few selected ones, and then you know, ask Georges for the answer hopefully.</p>
</div>
<div class="paragraph">
<p>So something I wanted to say is if you want a plain unit test with like no dependencies with the infrastrcuture you just can go and use your unit or whatever is your preferred framework. I think we have to say we did settle on JUnit 5, as the default framework to do testing, so we recommend you keep that for Quarkus, but then Quarkus has this interesting model where it&#8217;s fast enough or really fast to get started, to start itself therefore we can run the whole application in each of your tests, and then you can run in real life situation, right, is that correct?</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Yeah.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: You want me to share your screen. So, you show that a little bit or?</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Yeah, whatever you think.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: Yeah, sure, let&#8217;s get started with it. Unless you guys have some more introduction on the testing or would you&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p><strong>Max</strong>: No, sounds good to me!</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: No, I&#8217;m good.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: So there you go, Yeah, I do Skype. So this is a Quarkus app, right?</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Yes, this is a Quarkus application that I generated using my Maven tooling, so I haven&#8217;t changed anything, just created a Quarkus application opened it in IntelliJ which I&#8217;m using throughout this present. [unaudible, scattered] So you wanna talk about what these two-generated tests are?</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: Yeah, let&#8217;s start with the first one.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Yeah, got it, so, okay, cool. So like Emmanuel said, when we use JUnit 5 with Quarkus, our integration with Quarkus, what it does is that it starts Quarkus itself. The whole Quarkus application. And we envision like you run actual, hit the actual endpoints that your application uses, that&#8217;s not the only thing you can do. Of course, you can do a whole bunch of other stuff. But that&#8217;s like the main way we see it being used. So here you see the Quarkus test is our integration point with JUnit 5, and that&#8217;s all you need to do just to start your Quarkus application inside the test. And here is like you just write your regular test. We&#8217;re using REST-assured here, with Quarkus supports out of the box, so you&#8217;re hitting the Hallo endpoint expecting it&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: You don&#8217;t have to, by the way, but I think we integrate right away, the port and host that the Quarkus app is running with REST-assured. It&#8217;s like a total transparent experience for you.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Exactly, yeah, if we didn&#8217;t integrate out of the box, you would have to select here. You have to do port, like 8081 or whatever. Yeah, we do that out of the box. So it&#8217;s the experiences with no friction at all.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: Oh, speaking of&#8230;&#8203; So you put 8081 for a reason. So the default port, in Quarkus is 8080, so that&#8217;s how we start.</p>
</div>
<div class="paragraph">
<p>So historically, from WildFly and even before&#8230;&#8203; But for test we&#8217;ve decided to bump the port to one, so that you can run your test and while having your life application running, right?</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Yeah exactly, so exactly our default port for running the regular applications is 8080 but you bring your test 8081. so, we envision&#8230;&#8203; You can do multiple things in&#8230;&#8203; also the dev mode runs in 8080, so you can have your dev mode running and then your test like running separately. But just the way we have to that to make things.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: Can I change it?</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Yes, absolutely. You go here to Quarkus, well, this my&#8230;&#8203; IntelliJ Ultimate doesn&#8217;t have a property completion yet.</p>
</div>
<div class="paragraph">
<p>I know Max is working on it but there&#8217;s also a community plug-in, but I haven&#8217;t installed it yet&#8230;&#8203; But anyway, http port would be like 8080, say 9090 for the regular one.</p>
</div>
<div class="paragraph">
<p><strong>Max</strong>: Just get to clarify: IntelliJ, if you install the community Quarkus plug-in you should have&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Yeah, yeah, yeah, exactly. I haven&#8217;t installed that, but IntelliJ Ultimate out-of-the-box doesn&#8217;t have that, but I haven&#8217;t installed it so, if I wanted to change the port, Like let&#8217;s say 8082, I would just do this set Quarkus http.test-port. So like Emmanuel like to say a lot and I think it&#8217;s a great decision is that, everything in Quarkus is configured through the application properties so a whole bunch of our frameworks and libraries that we use are controlled in this manner. So you just have to learn a set of properties and you can figure out all the properties, like You go Quarkus&#8230;&#8203; Even if I.</p>
</div>
<div class="paragraph">
<p>I don&#8217;t have the IDE integration, but if I go to http reference on our web page we can see what all the properties are or not here, maybe like Quarkus testing, I usually just open the source code. So anyway, I&#8217;m not sure exactly where they are now. You remember that be great but usually the&#8230;&#8203; The properties are right on the site, so you can see exactly what you&#8217;re actually&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p>0:12:24 S1:</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: You can to me, let me take the&#8230;&#8203; One thing I liked and have to admit I went really kicking and screaming for that, but what I thought was really the best solution was for each guide to have the list of properties for it. So if you go to&#8230;&#8203; Sorry my network is suffering a bit apparently, so if I go to configuring data sources, here at some point, you see, here&#8217;s how I configure the data source and you might even have the complete list somewhere, I think, towards the end?</p>
</div>
<div class="paragraph">
<p>Yeah, there you go, you get a full page, here and we did two things. So one is this list here is actually generated from the list of properties we have in each of the in this specific extension. And you can filter stuff here. So if I am only looking for health check, then it doesn&#8217;t work.</p>
</div>
<div class="paragraph">
<p>Don&#8217;t know what&#8217;s going on&#8230;&#8203; Yeah, they go. So you got the filtering of the list of properties, so that&#8217;s useful too, if you got a big list of properties, but another one that is usedful is if you go back to quarkus.io/guides, here the second one. So Hey, the first one is, "Hey how do I continue my app? But the second one is, "Give me all of the possible quotes configurations ever".</p>
</div>
<div class="paragraph">
<p>And here you&#8217;ve got the massive list of properties, and you can really quick search something. So yeah, if I look for, I don&#8217;t know, SQL because I want the Hibernate way to find things where&#8230;&#8203; I guess I should have used&#8230;&#8203; you that there&#8217;s a bit too many here, but I should be able to find somehow fast enough. The&#8230;&#8203; There you go Hibernate ORM, then you see how do I get the logs?</p>
</div>
<div class="paragraph">
<p>So I log creator would have been been better.</p>
</div>
<div class="paragraph">
<p>So it&#8217;s a nice way to get all of the properties and filter them out very quickly. And I was against that. But since we have automated it, we said, Hey, why not? And it was actually, it is a very good, very good solution. So, back to Georgios now&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Yeah, thanks for that. Yeah, I was looking for those. But yeah, that&#8217;s exactly, yeah. How we envison people would find it more with the IDE integration, like VS code has it out of box and stuff like that.</p>
</div>
<div class="paragraph">
<p>So let&#8217;s go in like run a first test, right? So for my need it should just work. I&#8217;ll just hit it right here.</p>
</div>
<div class="paragraph">
<p>And what this will do is it will start the Quarkus application and will actually perform an http request, against the Hello endpoint. So if I go and change this to below here, then obviously my test fail, or then again, my test will fail because I expected "hello", and that&#8217;s it for the REST-assured stuff. So, REST-assured stuff integration out of the box.</p>
</div>
<div class="paragraph">
<p>This is a regular JVM application. When we write a Quarkus test, now we have another sort of test which we call the "native image test". Now, what this does is that it gives you the ability to build the GraalVM native image and run tests against that. So it&#8217;s like one&#8230;&#8203; Just one quick here, I can run and I can build the test that and both sorry. Yeah.</p>
</div>
<div class="paragraph">
<p>I haven&#8217;t configured IntelliJ to properly find everything here, but if I do mvn -verify -pNative what it will do after running the reading resource test it&#8217;ll run this test with Maven fail-safe if it&#8217;s an actual integration test and build the GraalVM native image as we&#8217;re seeing here.</p>
</div>
<div class="paragraph">
<p>And once it builds that it&#8217;ll start it and execute in this case it&#8217;ll execute the same rest endpoint; the same http request against the rest endpoint of the native image.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: Yeah, so if you&#8217;re unsure about the nature image that&#8217;s how you would do your extra smoke tests to make sure the native image is not doing something funky compared to the actual Java code.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Exactly&#8230;&#8203; Yeah, that&#8217;s exactly&#8230;&#8203; We see it as a black-box testing thing, where you can only test the parts of the application that are available from the outside, like http or messaging, or anything like that.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: By the way you said you forgot to configure your stuff in IntelliJ. I think it&#8217;s to export a property, which is GraalVM home, something like that&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Yeah, exactly.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: So you edit your test and you set an environment viable, which is GraalVM home, which will point to the native image generator, forgot the name of it.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Native yeah, native image, yeah. So yeah, exactly&#8230;&#8203; I configure it here, and then I would figure it out, and then everything would just work, but I didn&#8217;t do that now, but okay.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: He we got one question from <em>__</em>. Let&#8217;s try to extract something out of it so "Guys, please make a guide to test driven development and post from controller, service and repos in these video. Thank you for helping me, I have coffee on my POM, but inject more kind of return some error. I&#8217;m not sure what inject mock. Oh, I guess we gonna go and address the whole mock as a bit later. Maybe that would be a good time to dive into this.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Sure, sure, yeah, sounds good.</p>
</div>
<div class="paragraph">
<p><strong>Max</strong>: I do think the point here is the POST part. I think the point here is the post part, I assume, 'cause the GET part is easy, it&#8217;s more the post, the to&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Yeah, well, the post flow isn&#8217;t anything specific to Quarkus just you would use your rest assured, you just configure rest assured the rest assured test to do whatever it needs to do with POST.</p>
</div>
<div class="paragraph">
<p>Also, we can do that. Yeah, we can do that later but another thing we should mention is that our quick starts have most of this stuff implemented, already. So looking at the Quarkus quick starts is which I&#8217;ll pull up right here is a great way to see all the stuff that we envision as the proper way of doing things or have a lot of examples. So here it is: quarkus.io. quick starts, we have all the quite starts here. If I go for "POST" I&#8217;m pretty sure let&#8217;s find something.</p>
</div>
<div class="paragraph">
<p>Yeah, so it would be here, like the validation right here you can see an example of how you would do POST. So it&#8217;s here like you, it&#8217;s just rest assured there&#8217;s nothing Quarkus specific to this. But yeah, we can try it out.</p>
</div>
<div class="paragraph">
<p>So how, how we move on to something that&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: So we got one question from Recardo&#8230;&#8203; Is there a way, as the test runs the Quarkus app to automate the bootstrap of dependent system, which I think is gonna be a nice connection to test containers and how you can integrate it. So whenever you wanna jump on that we can&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Yeah, not exactly sure what Recardo means here, 'cause it could mean various things in the Quarkus space.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: I suppose it&#8217;s not a dependent system of the internal of the application here, we will see how you do mock, which would be a way to walk around that, but I assume he wants to start an external database.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Yeah, yeah, We&#8217;ll show that. Yeah, we&#8217;ll definitely show that. That&#8217;s one of the points that we really want to cover test containers.</p>
</div>
<div class="paragraph">
<p>So let&#8217;s start with something that we really hear a lot.</p>
</div>
<div class="paragraph">
<p>A lot of people wanna mock the REST client because we wanna start using REST client and then start testing it.</p>
</div>
<div class="paragraph">
<p>REST client is like super useful because every micro-service has to do http requests sooner or later, so anybody ends up using the REST client.</p>
</div>
<div class="paragraph">
<p>Let&#8217;s go ahead and start with creating an example. REST client, we wanna do. I wanna have a&#8230;&#8203; I&#8217;m gonna hit an external country service, so the first thing I wanna do is create a country let&#8217;s say, DTO, I give it two fields "name" and "capital".</p>
</div>
<div class="paragraph">
<p>Okay, let me just go ahead and use JSON B, so import as we support JSON, B and Jackson. Both for marshelling and marshelling Jason, I&#8217;m just gonna use this on here just for no particular reason. So let&#8217;s set up&#8230;&#8203; What can I do?</p>
</div>
<div class="paragraph">
<p><strong>Max</strong>: You could have done that with add-extension?</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Yes I could have done mvn add-extension. But since I&#8217;m already in the IDE, I just copy&amp;paste to here.</p>
</div>
<div class="paragraph">
<p>So, I&#8217;m just doing&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: It just means that adding an extension is literally adding something in the POM, so that&#8217;s&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Yes, no magic, yeah. So we have tooling to automate this.</p>
</div>
<div class="paragraph">
<p>So everybody&#8217;s work flow is different. My workflow is so for me it&#8217;s just easier to copy paste into pom.xml.</p>
</div>
<div class="paragraph">
<p>Other people couldn&#8217;t do it a lot differently.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: Yeah, I used to develop with X. so do you then&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: So, no I&#8217;ve always been an IntelliJ fan. So, we set up our DTO and now it&#8217;s actually set up with the REST client would look like. So, it&#8217;s a country services, so the REST client is declared. The whole idea is that you declare an interface, and then Quarkus will automatically implement that interface for you in order by generating a code that will use a http request. So what we&#8217;re gonna do here we&#8217;re gonna hit an external - we&#8217;re gonna try to use an external service. I&#8217;m gonna use this REST country service, right?</p>
</div>
<div class="paragraph">
<p><em>__</em> And I&#8217;m just gonna use one end point, which is the name endpoint which, as you can see here, what I wanna hit is this REST v2 main name, so that&#8217;s what I&#8217;m gonna try to set up here.</p>
</div>
<div class="paragraph">
<p>Country import&#8230;&#8203; get by name&#8230;&#8203; String name&#8230;&#8203; Yeah, this will be a GET as I can see here. Well, it doesn&#8217;t say it, but it is a GET anyway and return produces an application JSON and the path will see the whole path for the country for the version of the country service. I&#8217;m using under v2 as we see here.</p>
</div>
<div class="paragraph">
<p>And the path for <em><em>_ class is a name as </em>_</em> So that sets it up. I&#8217;m just gonna copy paste the URL. So like we said earlier, we can figure a lot of things through application properties. And since I wanna type this whole thing here, this is what you would configure. So basically when you&#8217;re building a REST client, Quarkus is building a REST client it needs to know what the base URL is and this is how we set the base URL so this is the name of the class.</p>
</div>
<div class="paragraph">
<p>Oh, I and you said this is the suffix of the property that we use in order to configure the base URL. So base URL is <em>__</em>.</p>
</div>
<div class="paragraph">
<p>And now, how we&#8217;re gonna call, how we&#8217;re gonna supposed to use this so; Well, I&#8217;m just gonna expose this as a rest API, so run building anything with business logic here, we just gonna fill the rest endpoint that will delegate to hitting don&#8217;t get to the REST client, to hit the rest endpoint of <em>__</em>.</p>
</div>
<div class="paragraph">
<p>I don&#8217;t know Emmanuel, I don&#8217;t know what your thoughts are on what this is supposed to call in the Spring world. We call this controller. I guess, here, in Quarkus we&#8217;ve been using resource, but I know talking to Stephane he didn&#8217;t really like that name. So I know what you guys think what your opinion is.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: I don&#8217;t have opinions really so.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: How about you, Max?</p>
</div>
<div class="paragraph">
<p><strong>Max</strong>: A control for me, it&#8217;s something I&#8217;d used.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: Yeah, I think, I&#8217;d use controller in my Play days.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Oh, okay, so that&#8217;s how Play did it, well, Okay. Here we go. So we&#8217;re injecting the country service, the interface into the&#8230;&#8203; We call it a resource here but when a partner is created at the REST client CDI qualifier. So when we&#8217;re injecting we have to use that qualifyer as well and this is done, because you might wanna create your own but in this case, we&#8217;re just using the qualifier to disambiquate if there are multiple services, multiple implementations of the country service. So I&#8217;m just gonna copy this here, and go and let&#8217;s see, this is GET&#8230;&#8203; And I&#8217;ll say, path name - name and <em>__</em>.</p>
</div>
<div class="paragraph">
<p>Okay, so now what I&#8217;ve done to set up a resource which will hit the REST client, but now I wanna test it, right, so I just&#8230;&#8203; I&#8217;ll create a new test.</p>
</div>
<div class="paragraph">
<p>I&#8217;ll say regular country resource test is gonna be a Quarkus test. And I&#8217;m just gonna copy this here.</p>
</div>
<div class="paragraph">
<p>So I basically have to do similar things is test <em><em>_. So </em>_</em>.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: <em>__</em>.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: No we&#8217;re out of the IMF.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: Well everybody is in at some point.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Yeah, I agree <em><em>_ away that behind us. So now what I&#8217;m gonna do here I&#8217;m gonna try and show what I expect it to return. So this is just standard rest assured syntax, so this will be the size here I expected to be one because when I hit the REST service it&#8217;ll give me one only. If I added like </em>_</em> return a lot more results, and I&#8217;ll go and I&#8217;ll say, the first result name is, the name is "Greece"</p>
</div>
<div class="paragraph">
<p><strong>Max</strong>: <em>__</em> path, right?</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Yes, yes, it&#8217;s <em>__</em>. Rest assured uses Jetty.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: Let me ask a question to the readers "Does anybody know why we started the video with the music from Star Wars? You can carry on on a&#8230;&#8203; Somebody picks that up.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Okay, so now I&#8217;m starting the test inside my browser&#8230;&#8203; Ah, we made a mistake here and I think I made a mistake.</p>
</div>
<div class="paragraph">
<p>Did I not add JSON on the REST client? JSON V could not find MessageBodyWriter&#8230;&#8203; ah&#8230;&#8203; Obviously I made a mistake. Produces then&#8230;&#8203; Yeah, I think it&#8217;s also I made a mistake here. I didn&#8217;t&#8230;&#8203; You gotta should have caught that returning Jason.</p>
</div>
<div class="paragraph">
<p><strong>Max</strong>: What was the error?</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: The error was that it told me that it couldn&#8217;t return an octet stream because I didn&#8217;t have his produces. So by default it is using ocetet stream and it couldn&#8217;t figure that out.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: May the fourth, so that&#8217;s why we had the sound&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Oh, so I made another mistake, I didn&#8217;t add getters here.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: While you figure that out, there was a question for Antony. "Hey gang, I can&#8217;t find a saved update <em>__</em> in Panache TTbase what&#8217;s wrong?"</p>
</div>
<div class="paragraph">
<p>So it&#8217;s a joke because Antony is a long time contributor and team member of the Hibernate before he went into the darker side of support, and then later training and certification. But it is a very good question and it&#8217;s a more complex than one could think, there is an open issue, but I suppose let&#8217;s keep that question for later in a specific Panache presentation that would be probably a good to exchange.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Yeah, you probably have to break it Stephane here and get in to describe all the nitty gritty of Panache.</p>
</div>
<div class="paragraph">
<p><strong>Max</strong>: So there&#8217;s a new question about the constructor&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: So I, yeahm is there any difference of injecting REST client in constructor instead of the instance variable?</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: No, there is not.</p>
</div>
<div class="paragraph">
<p>I just wanted to show it because I wanted to show&#8230;&#8203; Because in the CDI world or the Java EE world, whatever you wanna call it. A lot of people don&#8217;t use constructor injection. That was folks for the Spring world, think that, "Oh yeah, JavaEE doesn&#8217;t have constructor injection and all that weird stuff, but it&#8217;s been around forever. It&#8217;s just in all tutorials and stuff, you don&#8217;t see it being used that much. That&#8217;s just why I want to make the point here its just working out of the box, right&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: Yeah, that&#8217;s a good point, and it&#8217;s all done at compile time, so there&#8217;s no reflection really it&#8217;s all figured out at compile time. And we generate the right class to actually populate those either constructor or the setter and getter.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Yeah, that&#8217;s a huge differentiator.</p>
</div>
<div class="paragraph">
<p>So getting back to the test, I should actually get to work up. The assertion, was failing it was saying that the name wasn&#8217;t great and that was my fault 'cause I didn&#8217;t have getters hopefully now, but I should get everything working.</p>
</div>
<div class="paragraph">
<p>Pretty sure I will. All right, yeah, everything&#8217;s working. So as a super easy thing to do, I just wrote a REST client here. And I verified that it works, but what we were hearing from everybody was like, "Oh yeah, you know what, that&#8217;s cool, but&#8230;&#8203; And a lot of times I wanna mock this out. I don&#8217;t want to hit the real service. And that&#8217;s a very, very.</p>
</div>
<div class="paragraph">
<p><strong>Max</strong>: Just two things: I saw, I think <em>__</em> Or you couldn&#8217;t put regress client on this, right? Instead of putting it on a injection.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Oh yeah, I should have, yeah, actually I usually&#8230;&#8203; Yeah, I registered clients <em>__</em> you&#8217;re right.</p>
</div>
<div class="paragraph">
<p><strong>Max</strong>: But it&#8217;s equal to the same thing, right?</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: I&#8230;&#8203; Yeah, it&#8217;s the same thing, is the same thing as same thing. Actually, it&#8217;s a good point because I&#8217;m gonna have to update in order for the mocking to work that I&#8217;m gonna show it, I&#8217;m gonna have to update this, which is&#8230;&#8203; And I would have to make it application scope. I&#8217;ll explain exactly when we do that.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: While you do that, I can explain a little bit, before we go into marketing. So here, so far, most of our tests have been kind of black box, so we say, "Hey we go and connect to that URL and we do something. And what not, but Quarkus tests actually is a being inside your app, so you can literally inject other beans so you can do what I would call more like your gray box kind of test where you can inject one of the bean to do some more surgery into deciding what you wanna test, and going on. So, I suppose by side effect will show that inside mocking but I wanted to present that because even as you don&#8217;t do mocking its actual a very, very useful feature set.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Yeah, exactly, so in here, yeah, we in the test, if I did this <em><em>_ on free in this country sure with object and the REST client, then that&#8217;s exactly as Emmanuel was describing if I did this, I could use this inside the test anyway I wanted because exactly, like I mentioned this is a B, so we&#8217;re gonna show something a little different. So we wanna mock this right, so we want in&#8230;&#8203; When I do, when I hit </em>_</em>, I wanna have my own thing instead of hitting the REST service. So the whole idea here is that I added Quarkus JUnit 5 Mockito which integrates Mockito in JUnit 5 with our Quarkus CDI stuff.</p>
</div>
<div class="paragraph">
<p>So what you do here, when you call country service, and you would instead of inject you do inject mock, and because we need the qualifier, we&#8217;ll do REST Client. Like I said, same reason, we injected the&#8230;&#8203; We use the qualifier in the injection point here, this is another injection point, so we&#8217;re gonna use the qualifier but now we wanna control it so this will give us a mock of country service, a mock that we can control with Mockito.</p>
</div>
<div class="paragraph">
<p>That&#8217;s the great part, ups, sorry&#8230;&#8203; And then its, you just use Mockito the same way you&#8217;ve always been using it. Like I do not been using Mockito for a long time, and I always loved it and never, never thought to use any other mocking library.</p>
</div>
<div class="paragraph">
<p>So what I would do here, like I do Mockito when country service getByName please. And I would say, then the return collection <em><em>_ and let&#8217;s say new country, and instead of Greece let&#8217;s say </em><em> And </em>_</em> So now what I&#8217;ve done here is basically country service will be the mock and it will replace the regular CDI bean, but only for this task. And that&#8217;s a very important part that this test will continue to use the regular external URL when we&#8217;re hitting this test here is the only one that&#8217;s gonna use the mock and that&#8217;s really what mocks are for, like per test, let&#8217;s say, alteration of your application.</p>
</div>
<div class="paragraph">
<p>So if I go here, I expect to get <em>__</em> and I&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p><strong>Max</strong>: That&#8217;s probably a good what you run it. Just be clear that inject mock is actually a Quarkus annotation, right?</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: yes, yes exactly. I open imports here, it&#8217;s quarkus.test.junit5.mockito.inject.mock And now it&#8217;s failed, and I wanted it to fail because I need to explain why wait in this inject mock thing works. So inject mock works on normal scope CDI beans. Normal scope CDI beans are usually either application scope or request scope.</p>
</div>
<div class="paragraph">
<p>So, the Microprofile spec defines that when you create a REST client like this, and you don&#8217;t define a CDI scope that it&#8217;s dependent, it&#8217;s the dependent scope which practically means that in every injection point, you get a new instant self this country service, and that doesn&#8217;t allow us to create&#8230;&#8203; it doesn&#8217;t allow us to create a mock because it&#8217;s already a JDK dynamic proxy and Mockito can&#8217;t already mock dynamic. So we have to do&#8230;&#8203; We have to make this an application. So, by making this application scope this inject mock here will work and when I do and being clean test again, I should see all my tests passing now and they all pass.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: Somehow couldn&#8217;t we or <em>__</em> detect that hey, it&#8217;s dependent scope. But then in some tests we wanna do a mock. So let&#8217;s actually have some sort of fake different scope.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Yes, I got a&#8230;&#8203; Basically, we discuss this with Steward and Martin and&#8230;&#8203; Yeah, what we&#8217;re thinking is that we have some kind of bit code transformer that will be used and when you have this kind of inject mock thing, that will be used in it will alter the code of&#8230;&#8203; Of the country service itself to actually take the mock into account. So that&#8217;s something that&#8230;&#8203; That we&#8217;ll probably do sometimes soon&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: Okay, awesome. So we are 22 minutes before we end, so just a checkmark.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Okay, good. One more thing about the mock. So let&#8217;s say I do since I&#8217;m using Mockito, Mockito by default, when you don&#8217;t define something, or turn a default response.</p>
</div>
<div class="paragraph">
<p>So if I do like country France and since I have it mocked, I haven&#8217;t told it what to do for France. What it will do is, it will return an empty list. So that&#8217;s just a Mockito thing I wanted everybody to be aware of.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: I just&#8230;&#8203; I wanted to clarify, to Igor. This problem with the mock that cannot be the dependent type that cannot be mocked. So the workaround is to use application scope on your service, and that will be the workaround right now until we have a proper solution inside Quarkus, but that works actually that should have been application scope most likely anyways.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Yes exactly, yeah the only reason it wasn&#8217;t is the spec defines that it should be dependent scope by default. Otherwise, I would have just made it application scope.</p>
</div>
<div class="paragraph">
<p><strong>Max</strong>: So, we got another one. Georgio. Wanna take that, Emmanuel? How to mock REST client?</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: How do I mock REST client test object to throw a 500 exception, http 500, but not using Mockito on his Quarkus annotation @mock and Eclipse Microprofile register client?</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: I don&#8217;t think you can&#8230;&#8203; Like with a mock, right?</p>
</div>
<div class="paragraph">
<p>I don&#8217;t think you can mock it to tail it, to return a 500. Well, what you can always do with Marketo is to tell it to throw an exception, but through annotations is&#8230;&#8203; I don&#8217;t think you can do that. I don&#8217;t have anything, I can&#8217;t recall of anything but I would argue that if you were going to test something like that, you probably want to do what I wanna do now.</p>
</div>
<div class="paragraph">
<p>Oh, which is to actually use, to have the&#8230;&#8203; Not mock the REST client, but to mock the external service.</p>
</div>
<div class="paragraph">
<p>So, what I planned to show now is that we continue to use the regular REST client, but instead of using the external rest countries service that I was using, I want to start a service like a proxy let&#8217;s say, that will intercept all the request to that service and in there, I can make it return 500, I can make it return 404, I can make it return any kind of error I want in order to test my actual integration. So in my view, that would be the proper way to test like http errors.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: That also answers <em>__</em> sorry about butchering our first name, which is&#8230;&#8203; Inject mock is grateful functionality test, but is there a way to verify that the correct annotations are used on the REST client and that would be exactly that. So you would have your server being a custom one and you redirect to that server and then you can run the properties, with the REST client in a fully control environment.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Yeah, I think that&#8217;s the best way to test the end to end integration. That&#8217;s what I&#8217;m gonna do.</p>
</div>
<div class="paragraph">
<p>Okay, so let&#8217;s go like country service. If we do create a test to country service, this would be a Quarkus test and I&#8217;ll say <em>__</em>.</p>
</div>
<div class="paragraph">
<p>And I say, country service, inject client. Not the Junit assertions, I want the AssertJ assertions, are for that country service.</p>
</div>
<div class="paragraph">
<p><em><em>_ Unaudible typing! ! </em>_</em>. So this test, I haven&#8217;t been adding anything special to this test yet. I just wanted to set it up to show you that, what we&#8217;re gonna do here is that we&#8217;re gonna use the country service, but we&#8217;re gonna hit an external end point that will be controlled by us. Once I said once I get this going&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p>I passed the test&#8230;&#8203; Now, we&#8217;re gonna introduce one more concept that is specific to Quarkus, then we&#8217;re gonna use WireMock in order to demonstrate.</p>
</div>
<div class="paragraph">
<p>So like Emmanuel said earlier, we run, we boot Quarkus once and then we run all the tests, against it. And what that means is that when you want to do something before you boot Quarkus you need as a developer, you need an integration point.</p>
</div>
<div class="paragraph">
<p>Well, the Quarkus test resource is that integration point that you&#8217;re looking for.</p>
</div>
<div class="paragraph">
<p>So wiremock contries&#8230;&#8203; So I gotta create such an integration point or what I&#8217;m planning to do is now I&#8217;m planning to create a WireMock server where I mock, I set up basically the endpoints that I care about, and our test is actually gonna hit that server. How we do that? So we&#8230;&#8203; We at this Quarkus test annotation test resource annotation we create a class that implements this Quarkus test resource lifecycle manager.</p>
</div>
<div class="paragraph">
<p>The stuff we care about, the methods with care. Are in here, or start which basically is the method that Quarkus calls back into the Quarkus test calls back into before it launches the Quarkus application, and what it returns is a set of properties that&#8217;s runtime properties that Quarkus, That will affect how Quarkus runs. This call is when Quarkus finishes, all the tests finish. So what we do here is a WireMock server.</p>
</div>
<div class="paragraph">
<p>WireMock server = new WireMockServer <em>__</em>;</p>
</div>
<div class="paragraph">
<p>server.start <em>__</em>;</p>
</div>
<div class="paragraph">
<p>And now, since we&#8217;re actually kinda running out of time, I just gonna copy&amp;paste the actual mocking part.</p>
</div>
<div class="paragraph">
<p>I copied it from the stuff that I have already. And we&#8217;ll share with you being in the presentation so you can follow along. I&#8217;m gonna make this a Java 14, I&#8217;m on 14 now. I also have to&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: You wanna use the multi line, the the text which is.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Exactly exactly, that&#8217;s exactly what I wanna use because as I hate writing JSON inside the little&#8230;&#8203; , the regular Java stuff is just terrible.</p>
</div>
<div class="paragraph">
<p>So in order to do that, I need to enable some previews stuff.</p>
</div>
<div class="paragraph">
<p>So, Maven compile&#8230;&#8203; This stuff isn&#8217;t actually important for the actual test, but it&#8217;s cool to see, show with Quarkus we have all the&#8230;&#8203; all the flexibility to do anything you&#8217;re used to with Maven, or whatever to a&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: So it works with Java 14?</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Oh yeah, absolutely, absolutely.</p>
</div>
<div class="paragraph">
<p>It doesn&#8217;t work with records just yet, but we have a PR ready for that, so it should be working very soon.</p>
</div>
<div class="paragraph">
<p><strong>Max</strong>: So you basically show what people can use in like four or five years in the production, so to&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: No, no, they can use it right now.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: Quarkus goes very well with the production, guys.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Yeah, why not? So I have to enable preview both to compile and for surefire while running otherwise it will work, and I have to tell IntelliJ to use it causes not smart enough to figure out how I configure it.</p>
</div>
<div class="paragraph">
<p>So basically what I&#8217;m doing here is that I was subbing out the&#8230;&#8203; the end point that this method is looking for and I&#8217;m saying when you see "gr" don&#8217;t return the regular green stuff, but return the same name, angry. So I&#8217;m actually just actually wrote Greek. And the other thing I did is that here, I told it to forward all the stuff that didn&#8217;t match here, I told it to forward to the actual, actual service and I need to do one more thing to get this working I need to tell Quarkus to use this actual, this server.</p>
</div>
<div class="paragraph">
<p>So, this serverm, once it started, it&#8217;ll start at some URL, some port&#8230;&#8203; I don&#8217;t know which, but don&#8217;t really care because all I have to do in order to make the country service work, I need to tell it where the URL is, but wiremock base URL gives me that information. So what this does is that it overrides the property that I have here, which is the default. Let&#8217;s say this gets overridden by when I start here, because like I said, these properties that are returned by start or runtime properties that override, what&#8217;s in application properties.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: One of the question is, Is there a doc somewhere that goes into details at everybody&#8217;s own pace, that&#8217;s a lot of information that.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Yes, I know, no, because I just came up with this when I was preparing for this.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: There you go YouTube like driven features.</p>
</div>
<div class="paragraph">
<p><strong>Max</strong>: The feature is there it&#8217;s just the example is new.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Yeah, I need to write down the example. Yeah, because this is a lot of information that it&#8217;s not&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p><strong>Max</strong>: Once you&#8217;re done here, take this code and commit into a repo and push it, then we can go.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: I&#8217;ve already done that I&#8217;ll share once this is done, I&#8217;ll show you the URL.</p>
</div>
<div class="paragraph">
<p><strong>Max</strong>: What&#8217;s the thing that&#8230;&#8203; Like this start? What was the thing that made it whats the thing that made that being picked up? The lifecycle manager?</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Yes, the Quarkus test resource and it picks up these life cycle managers and I could have multiple lifecycle managers, I have one for database or whatever and they all run before Quarkus starts. That&#8217;s the important part. They run before Quarkus starts and they can override runtime properties.</p>
</div>
<div class="paragraph">
<p><strong>Max</strong>: Very cool. So I was wondering about that.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: We have 10 minutes left, we haven&#8217;t showed the test containers, which is one of the questions we had. So let&#8217;s go do that.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Yes, yes let&#8217;s do that really quick okay. So, I stay <em>__</em> and going to test containers, I wanna copy paste the dependencies from here, I need to get to to do, let&#8217;s see, okay.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: <em>__</em> this is getting awkward.</p>
</div>
<div class="paragraph">
<p>Test containers for information for people that don&#8217;t know is&#8230;&#8203; Well, it&#8217;s a way to start from your, to control by your test life cycle, starting a set of resources inside a Docker container, on the same machine. And maybe on other machines like I don&#8217;t quite know, but the idea is you control the Docker start and stop of a database or JMS queue, or whatever you want to run your integration test. That&#8217;s very, very useful for that.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Absolutely, absolutely. Yeah, we get that question a lot. So we really need to show this. So I just copy&amp;pasted the Hibernate Panache ORM dependency, postgresql driver.</p>
</div>
<div class="paragraph">
<p>Oh, well, probably Panache, mock out for later. So you can talk about that when you have Stephane on the show. Since this is a feature coming in 1.5, it&#8217;s not in yet.</p>
</div>
<div class="paragraph">
<p>Okay, so let&#8217;s go create an entity "route". So that entity <em>__</em>.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: And here&#8217;s a good one. So, Antonio sais: what about debugging your test? I find it cumbersome to attache the debugger in IntelliJ, I think I see&#8230;&#8203; Yeah, that&#8217;s for the test, okay, put it in on. It&#8217;s not&#8230;&#8203; <em>__</em> any applications running any testing running in IntelliJ to run the plain Java application from IntelliJ and attach the debugger&#8230;&#8203; Now that we have the command mode that&#8217;s much easier. I don&#8217;t know about test like what would you&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: This will work if I do this, let me hit, okay, I&#8217;m at Country service, if I go to country resource like yeah.</p>
</div>
<div class="paragraph">
<p><strong>Max</strong>: If you&#8217;re in a test just click that debug in anything.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: <em>__</em> you don&#8217;t work well now I&#8217;ve had it a bunch, of dependencies, but yeah, I got this thing. A regular testing out delete anyway, so let&#8217;s say I did this now I have all the Hibernate stuff inside, let me take-out Hibernate, so I then&#8230;&#8203; So the.</p>
</div>
<div class="paragraph">
<p><strong>Max</strong>: Are you trying, just to add the test containers on top or what are your&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Yeah, I was, I was starting the test containers thing. Yeah, exactly, but now I wanna show the actual debug&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p>See, debugging works just like any other Java application JUnit test, it&#8217;ll work because the idea, it works because it&#8217;s in the same JVM, I mean the test runs inside the same, the application and the test run inside the same JVM.</p>
</div>
<div class="paragraph">
<p>So debugging, just works.</p>
</div>
<div class="paragraph">
<p>What is a little cumbersome at the moment is dev mode inside the IDE. So with dev mode the easiest way to do it is you do mvn quarkus: dev and then you attach a remote debugger later on.</p>
</div>
<div class="paragraph">
<p>And most people are used to that work flow because they&#8217;re used to running their java-jar from the IDE or wherever, all the time. But with Quarkus dev mode, it&#8217;s a little different.</p>
</div>
<div class="paragraph">
<p>You just start it on the command line, you forget about it and you attach a remote debugger.</p>
</div>
<div class="paragraph">
<p>And that&#8217;s how I&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p><strong>Max</strong>: So I just&#8230;&#8203; You to add to that, VS code actually does it when you do, it sets up a default launch, the you press F5, it will start quarkus dev and connect a debugger for you, so you don&#8217;t&#8230;&#8203; And I didn&#8217;t actually realize this until Fred told me that its so lightweight and I think we&#8217;ve got&#8230;&#8203; I wanna see that we have the same thing to IntelliJ and Eclipse&#8230;&#8203; 'cause it&#8217;s just, it&#8217;s nice 'cause I&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Yeah, it&#8217;s awesome 'cause people expect it to work, they don&#8217;t understand that it&#8217;s not obvious, like when you start Quarkus dev mode then a different process starts and that&#8217;s the process you have to connect the debugger to. Yeah, it&#8217;s not exactly obvious. So yeah, having&#8230;&#8203; That would be great IntelliJ as well.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: Alright, let&#8217;s go back to test containers.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Yes, yes, yes, I&#8230;&#8203; Let&#8217;s finish that up. So, fruit resource I can, I created a fruit entity. With Panache I obviously don&#8217;t have to write almost any code, so everything will just work out of the box. So, I go public List fruit.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: By the way, we should have even less code at some points in the near future, so just as a teaser&#8230;&#8203; From a resource talking to Panache entity.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Yeah, you know what&#8217;s coming.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: I don&#8217;t know when, that&#8217;s the problem&#8230;&#8203; I live in the future.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: The PR I think, is pretty much raised. Stephane is reviewing it but we should be close. Ahhh fruit listAll&#8230;&#8203; Okay, so this will just list all&#8230;&#8203; And I now I need to do create fruit resource test&#8230;&#8203; And this would be a Quarkus test and now when I add a different test resource, a Quarkus test resource. So I need to start the database before Quarkus starts, right?</p>
</div>
<div class="paragraph">
<p>So if I go here, and d test containers, database.class, create a class then again will be a Quarkus resource manager, and since we don&#8217;t have much time I&#8217;m gonna copy&amp;paste it.</p>
</div>
<div class="paragraph">
<p>So what it does here basically is I&#8217;ll write this real quick and then explain what does&#8230;&#8203; So the idea is, the resource with a test resource lifecycle manager will start a it&#8217;ll start a test containers postgress skill database.</p>
</div>
<div class="paragraph">
<p>So here I&#8217;ve told it version 11.7 with database name, username, password, thats just some simple defaults and the important part here that start, I start the database, and then I define the Quarkus runtime properties, so that would be the data source runtime properties. That be the user name, the password in the URL and just like WireMock did same way post the test containers gives me a JDBC URL that I can just use.</p>
</div>
<div class="paragraph">
<p>So this way I just, I don&#8217;t have to configure anything with darker and pom.xml or have a Docker container, running anywhere other way I just integrated with Quarkus test containers and it&#8217;ll just work. I need to fix a few more things to make this work out of the box, the, this is the test specific that I&#8217;m telling it, it&#8217;s a database, Postgress databas, drop and create the database for the test. I&#8217;m gonna seed the database but some data and you just&#8230;&#8203; So, fruit and I need to copy like let&#8217;s say this that because the&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p><strong>Max</strong>: That is just using test containers? And I guess the only thing I had to do is used a wiring up with the Quarkus test resource.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Yes, exactly, Yeah, to start test containers before Quarkus starts.</p>
</div>
<div class="paragraph">
<p>So this should be always plain. I seeded the database with three fruits and that&#8217;s why in my test I said that I&#8217;m expecting three&#8230;&#8203; I&#8217;m definitely&#8230;&#8203; Okay&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p><strong>Max</strong>: Java 14&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: So sdk man, I totally endorse it as the way to use Java 14. and now just running again and let&#8217;s see. So, test containers starting here, we saw it did we started, test passed and it was not easy, right? So you saw it&#8230;&#8203; All I need is a test resource start the database on the important thing is to set the property, the runtime properties, I need and it just works.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: So just quickly taking the <em>__</em> sdkman.io and it&#8217;s a way to select the Java you want and a few other things.</p>
</div>
<div class="paragraph">
<p>You got a bunch of options here, but if you jumped from one JDK to another, the GraalVM one or just hte non-GraalVM one. A very useful tool.</p>
</div>
<div class="paragraph">
<p>You also show the test containers. And I wanted to show that it&#8217;s not limited to databases you&#8217;ve got quite a bunch of other things like Kafka, elastic search, <em>__</em> etcetera, etcetera. So that&#8217;s quite good. And integrate with JUnit 5, which is the one thing we&#8217;re using right now, so that&#8217;s&#8230;&#8203; There is one tiny things, they don&#8217;t do which is really sad, is they do require the Docker demon, which means we can not use that with podman, which is a bit of a shame 'cause that would be super useful&#8230;&#8203; But otherwise it&#8230;&#8203; It&#8217;s working great yep.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Yeah, hopefully that will restriction will be lifted&#8230;&#8203; We may be lifting soon, who knows., well, we have&#8230;&#8203;</p>
</div>
<div class="paragraph">
<p><strong>Max</strong>: We hit the hour. Is there anything else you wanna do?</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Well, yeah, basically the URL for all the code I showed you can find it. I know how it is posed to share. Do I just post it in the chat?</p>
</div>
<div class="paragraph">
<p><strong>Max</strong>: Yeah, I just toss it in chat, and then we will put in the blog when it&#8217;s coming out, yeah.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Oh, okay, great, great, you on.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: Okay, and tell us how you felt. Was it too technical, not technical, enough, too fast, too small to be perfect, to perfect or&#8230;&#8203; And then on the chat live, when it&#8217;s still alive, otherwise go to the video, post comments in there and don&#8217;t forget to subscribe to the Quarkus challenge or YouTube.com/quarkusio. I realize you don&#8217;t need the "c" here, So let me remove it, click here, there you go&#8230;&#8203; YouTube.com/quarkusio - hit subscribe and I&#8217;m not sure if it&#8217;s gonna be a weekly event, or bi-weekly event bi-weekly meaning every two weeks for the confusing English. People like me.</p>
</div>
<div class="paragraph">
<p><strong>Max</strong>: No questions?</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: Yeah, there&#8217;s one question, so let me go back to&#8230;&#8203; "So why did you prefer Maven over Gradle?</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: For the simple reason that I&#8217;m more familiar with it, right?</p>
</div>
<div class="paragraph">
<p>Quarkus works with both let&#8217;s say some of the edge cases like the very edge cases, work better with Maven, the Gradle support is being looked into it&#8217;s going to get way better over time. But the reason I used it is because I&#8217;m more familiar with Maven.</p>
</div>
<div class="paragraph">
<p><strong>Max</strong>: The essence of the Maven/Gradle discussion is, So there&#8217;s some issues we can&#8217;t fully handle in Gradle yet but we are hoping to fix it, but I also wanna say as far as we know, right now, about 70% of the people who goes to code.quarkus.io of chose Maven and the other chose Gradle.</p>
</div>
<div class="paragraph">
<p>So yeah, it&#8217;s a bit&#8230;&#8203; They&#8217;ll be improved, yeah.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: And Georgios was too fast, so we need slower coders.</p>
</div>
<div class="paragraph">
<p>Indeed there is a little bit of a lag with YouTube Live, hopefully it won&#8217;t be too visible in the actual final video once it&#8217;s all fully uploaded and properly run, but although it&#8230;&#8203; Good feedback on that.</p>
</div>
<div class="paragraph">
<p><strong>Max</strong>: Alright, we&#8217;re good.</p>
</div>
<div class="paragraph">
<p><strong>Emmanuel</strong>: Yeah, we&#8217;re good, thank you everyone and see you, well, sometime in the future sees <em>__</em> what we&#8217;re gonna try and do, but who knows? And happy May the Fourth to everyone.</p>
</div>
<div class="paragraph">
<p><strong>Georgios</strong>: Thank you everybody!</p>
</div>
</div>
</div>
              
          </div>
          <div class="width-12-12"><div class="share-page">
  <a class="share-linkedin" href="https://www.linkedin.com/shareArticle?mini=true&url=https://quarkus.io/blog/insights-1/&title=Quarkus Insights #1: Tests" rel="nofollow" target="_blank" title="Share on LinkedIn">
    <img src="/assets/images/share-page/icons_social-linkedin.png"/>
  </a>
  <a class="share-twitter" href="https://twitter.com/intent/tweet?text=Quarkus Insights #1: Tests&url=https://quarkus.io/blog/insights-1/&via=quarkusio&related=quarkusio" rel="nofollow" target="_blank" title="Share on Twitter">
    <img src="/assets/images/share-page/icons_social-twitter.png"/>
  </a>
  <a class="share-facebook" href="https://facebook.com/sharer.php?u=https://quarkus.io/blog/insights-1/" rel="nofollow" target="_blank" title="Share on Facebook">
    <img src="/assets/images/share-page/icons_social-facebook.png"/>
  </a>
  <a class="share-reddit" href="http://www.reddit.com/submit?url=https://quarkus.io/blog/insights-1/" onclick="window.open(this.href, 'pop-up', 'left=20,top=20,width=900,height=500,toolbar=1,resizable=0'); return false;" title="Share on Reddit" >
    <img src="/assets/images/share-page/icons_social-reddit.png"/>
  </a>
  <a class="share-email" href="mailto:?subject=Quarkus Insights #1: Tests&amp;body=Quarkus Insights #1: Tests https://quarkus.io/blog/insights-1/" title="Share via Email" >
    <img src="/assets/images/share-page/icons_social-email.png"/>
  </a>
</div>
</div>
        </div>
      </div>
    </div>
  </div>
</div>

  </div>

  <div class="content project-footer">
  <div class="footer-section">
    <div class="logo-wrapper">
      <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_reverse.svg" class="project-logo" title="Quarkus"></a>
    </div>
  </div>
  <div class="grid-wrapper">
    <p class="grid__item width-3-12">Quarkus is open. All dependencies of this project are available under the <a href='https://www.apache.org/licenses/LICENSE-2.0' target='_blank'>Apache Software License 2.0</a> or compatible license.<br /><br />This website was built with <a href='https://jekyllrb.com/' target='_blank'>Jekyll</a>, is hosted on <a href='https://pages.github.com/' target='_blank'>Github Pages</a> and is completely open source. If you want to make it better, <a href='https://github.com/quarkusio/quarkusio.github.io' target='_blank'>fork the website</a> and show us what you’ve got.</p>

    
      <div class="width-1-12 project-links">
        <span>Navigation</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="/">Home</a></li>
          
            <li><a href="/guides">Guides</a></li>
          
            <li><a href="/community/#contributing">Contribute</a></li>
          
            <li><a href="/faq">FAQ</a></li>
          
            <li><a href="/get-started">Get Started</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Contribute</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://twitter.com/quarkusio">Follow us</a></li>
          
            <li><a href="https://github.com/quarkusio">GitHub</a></li>
          
            <li><a href="/security">Security&nbsp;policy</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Get Help</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://groups.google.com/forum/#!forum/quarkus-dev">Forums</a></li>
          
            <li><a href="https://quarkusio.zulipchat.com">Chatroom</a></li>
          
        </ul>
      </div>
    

    
      <div class="width-3-12 more-links">
        <span>Quarkus is made of community projects</span>
        <ul class="footer-links">
          
            <li><a href="https://vertx.io/" target="_blank">Eclipse Vert.x</a></li>
          
            <li><a href="https://microprofile.io" target="_blank">Eclipse MicroProfile</a></li>
          
            <li><a href="https://hibernate.org" target="_blank">Hibernate</a></li>
          
            <li><a href="https://netty.io" target="_blank">Netty</a></li>
          
            <li><a href="https://resteasy.github.io" target="_blank">RESTEasy</a></li>
          
            <li><a href="https://camel.apache.org" target="_blank">Apache Camel</a></li>
          
            <li><a href="https://code.quarkus.io/" target="_blank">And many more...</a></li>
          
        </ul>
      </div>
    
  </div>
</div>
  <div class="content redhat-footer">
  <div class="grid-wrapper">
    <span class="licence">
      <i class="fab fa-creative-commons"></i><i class="fab fa-creative-commons-by"></i> <a href="https://creativecommons.org/licenses/by/3.0/" target="_blank">CC by 3.0</a> | <a href="https://www.redhat.com/en/about/privacy-policy">Privacy Policy</a>
    </span>
    <span class="redhat">
      Sponsored by
    </span>
    <span class="redhat-logo">
      <a href="https://www.redhat.com/" target="_blank"><img src="/assets/images/redhat_reversed.svg"></a>
    </span>
  </div>
</div>


  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" integrity="sha384-8gBf6Y4YYq7Jx97PIqmTwLPin4hxIzQw5aDmUg/DDhul9fFpbbLcLh3nTIIDJKhx" crossorigin="anonymous"></script>
  <script type="text/javascript" src="/assets/javascript/mobile-nav.js"></script>
  <script type="text/javascript" src="/assets/javascript/scroll-down.js"></script>
  <script src="/assets/javascript/satellite.js" type="text/javascript"></script>
  <script src="https://quarkus.io/guides/javascript/config.js" type="text/javascript"></script>
  <script src="/assets/javascript/search-filter.js" type="text/javascript"></script>
  <script src="/assets/javascript/back-to-top.js" type="text/javascript"></script>
</body>

</html>
